import { _decorator, AudioClip } from "cc";
import {
  EventType,
  GameItem,
  ItemStatus,
  ItemType,
  TriggerStatus,
} from "../model";
import Singleton from "../base/Singleton";
import { EventManager } from "./event-manager";
import { AudioMgr } from "./audio-mgr";
const { ccclass } = _decorator;

@ccclass("DataManager")
export class DataManager extends Singleton {
  static get Instance(): DataManager {
    return super.getInstance<DataManager>();
  }

  readonly Correct_Answer = [1, 2, 3, null, 4, 5, 6];

  readonly Origin_Answer = [6, 5, 4, null, 3, 2, 1];

  private _curAnwer = this.Origin_Answer;

  private _items: Array<GameItem> = [
    { type: ItemType.Key, status: ItemStatus.InScene },
    { type: ItemType.Mail, status: ItemStatus.NoExist },
  ];

  private _curItemType: ItemType = null;

  private _itemSelected = false;

  private _mailBoxStatus: TriggerStatus = TriggerStatus.Pending;

  private _grandmaStatus: TriggerStatus = TriggerStatus.Pending;

  private _h2aStatus: TriggerStatus = TriggerStatus.Pending;

  private _grandmaWordIndex = -1;

  private _isAudioPlaying = false;

  private _curAudioClip: AudioClip = null;

  get isAudioPlaying() {
    return this._isAudioPlaying;
  }

  getCurAudioClip() {
    return this._curAudioClip;
  }

  playAudio(audio: AudioClip) {
    this._curAudioClip = audio;
    AudioMgr.Instance.play(audio);
    this._isAudioPlaying = true;
  }

  get curAnwer() {
    return this._curAnwer.slice();
  }

  resetAnser() {
    this._curAnwer = this.Origin_Answer;
    this.triggerRender();
  }

  isCorrectAnswer(answer: number[]) {
    return (
      answer.length === this.Correct_Answer.length &&
      answer.every((item, index) => item === this.Correct_Answer[index])
    );
  }

  updateAnser(answer: number[]) {
    this._curAnwer = answer;
    if (this.isCorrectAnswer(answer)) {
      this._h2aStatus = TriggerStatus.Resolved;
    }

    this.triggerRender();
  }

  get mailBoxStatus() {
    return this._mailBoxStatus;
  }

  get grandmaStatus() {
    return this._grandmaStatus;
  }

  get h2aResoleved() {
    return this._h2aStatus === TriggerStatus.Resolved;
  }

  get items() {
    return this._items;
  }

  get itemSelected() {
    return this._itemSelected;
  }

  get grandmaWordIndex() {
    return this._grandmaWordIndex;
  }

  setGrandmaWordIndex(index: number) {
    this._grandmaWordIndex = index;
    this.triggerRender();
  }

  selectItem() {
    this._itemSelected = true;
    this.triggerRender();
  }

  cancelSelect() {
    this._itemSelected = false;
    this.triggerRender();
  }

  getPackItems() {
    return this._items.filter((item) => item.status === ItemStatus.InPack);
  }

  get curItemType() {
    return this._curItemType;
  }

  setCurItemType(type: ItemType) {
    this._curItemType = type;
    this.triggerRender();
  }

  collectItem(type: ItemType) {
    this._items = this._items.map((item) => {
      if (item.type === type) {
        item.status = ItemStatus.InPack;
      }
      return item;
    });

    this._curItemType = type;

    this.cancelSelect();
  }

  getItemByType(type: ItemType) {
    return this.items.find((item) => item.type === type);
  }

  useItem(type: ItemType) {
    this._items = this._items.map((item) => {
      if (item.type === type) {
        item.status = ItemStatus.NoExist;
      }
      return item;
    });

    this.onItemUsed(type);

    const packItems = this.getPackItems();
    this._curItemType = packItems.length > 0 ? packItems[0].type : null;

    this.cancelSelect();
  }

  onItemUsed(type: ItemType) {
    switch (type) {
      case ItemType.Key:
        this.onKeyUsed();
        break;
      case ItemType.Mail:
        this.onMailUsed();
        break;
    }
  }

  onKeyUsed() {
    const mailItem = this.getItemByType(ItemType.Mail);
    mailItem.status = ItemStatus.InScene;
    this._mailBoxStatus = TriggerStatus.Resolved;
    this.triggerRender();
  }

  onMailUsed() {
    const mailItem = this.getItemByType(ItemType.Mail);
    mailItem.status = ItemStatus.NoExist;
    this._grandmaStatus = TriggerStatus.Resolved;
    this._grandmaWordIndex = 0;
    this.triggerRender();
  }

  triggerRender() {
    EventManager.Instance.emit(EventType.Render);
  }
}
